using System;
using System.Runtime.InteropServices;
using System.Windows;

namespace GameOverlayWPF.Services
{
    /// <summary>
    /// 鼠标控制服务 - 用于在全屏游戏中释放和恢复鼠标控制
    /// </summary>
    public class MouseControlService
    {
        private static MouseControlService? _instance;
        private static readonly object _lock = new object();
        private bool _isMouseReleased = false;
        private RECT _savedClipRect = new RECT();
        private int _cursorShowCount = 0;

        public static MouseControlService Instance
        {
            get
            {
                if (_instance == null)
                {
                    lock (_lock)
                    {
                        if (_instance == null)
                        {
                            _instance = new MouseControlService();
                        }
                    }
                }
                return _instance;
            }
        }

        private MouseControlService()
        {
            System.Diagnostics.Debug.WriteLine("[MouseControlService] 鼠标控制服务已初始化");
        }

        #region Windows API

        [DllImport("user32.dll")]
        private static extern bool ReleaseCapture();

        [DllImport("user32.dll")]
        private static extern bool GetClipCursor(out RECT lpRect);

        [DllImport("user32.dll")]
        private static extern bool ClipCursor(ref RECT lpRect);

        [DllImport("user32.dll")]
        private static extern bool ClipCursor(IntPtr lpRect);

        [DllImport("user32.dll")]
        private static extern int ShowCursor(bool bShow);

        [DllImport("user32.dll")]
        private static extern bool SetCursorPos(int X, int Y);

        [DllImport("user32.dll")]
        private static extern bool GetCursorPos(out POINT lpPoint);

        [StructLayout(LayoutKind.Sequential)]
        private struct RECT
        {
            public int Left;
            public int Top;
            public int Right;
            public int Bottom;

            public bool IsEmpty => Left == 0 && Top == 0 && Right == 0 && Bottom == 0;
        }

        [StructLayout(LayoutKind.Sequential)]
        private struct POINT
        {
            public int X;
            public int Y;
        }

        #endregion

        /// <summary>
        /// 释放游戏的鼠标控制 - 在覆盖层窗口显示时调用
        /// </summary>
        public void ReleaseMouse()
        {
            try
            {
                if (_isMouseReleased)
                {
                    System.Diagnostics.Debug.WriteLine("[MouseControlService] ⚠ 鼠标已经释放，跳过重复操作");
                    return;
                }

                System.Diagnostics.Debug.WriteLine("[MouseControlService] 🔓 开始释放游戏鼠标控制...");

                // 1. 释放鼠标捕获（游戏可能通过SetCapture锁定鼠标）
                bool captureReleased = ReleaseCapture();
                System.Diagnostics.Debug.WriteLine($"[MouseControlService] ReleaseCapture: {(captureReleased ? "成功" : "失败")}");

                // 2. 保存当前的鼠标裁剪区域（游戏可能通过ClipCursor限制鼠标范围）
                bool clipSaved = GetClipCursor(out _savedClipRect);
                if (clipSaved && !_savedClipRect.IsEmpty)
                {
                    System.Diagnostics.Debug.WriteLine($"[MouseControlService] 保存鼠标裁剪区域: Left={_savedClipRect.Left}, Top={_savedClipRect.Top}, Right={_savedClipRect.Right}, Bottom={_savedClipRect.Bottom}");
                }

                // 3. 解除鼠标裁剪限制（允许鼠标在整个屏幕移动）
                bool clipRemoved = ClipCursor(IntPtr.Zero);
                System.Diagnostics.Debug.WriteLine($"[MouseControlService] ClipCursor(NULL): {(clipRemoved ? "成功" : "失败")}");

                // 4. 确保光标可见（游戏可能隐藏了光标）
                // ShowCursor返回显示计数器，负数表示隐藏，正数表示显示
                // 需要多次调用直到光标可见
                _cursorShowCount = 0;
                int showCount = ShowCursor(true);
                while (showCount < 0 && _cursorShowCount < 10) // 最多尝试10次
                {
                    showCount = ShowCursor(true);
                    _cursorShowCount++;
                }
                System.Diagnostics.Debug.WriteLine($"[MouseControlService] ShowCursor: 显示计数={showCount}, 调用次数={_cursorShowCount}");

                // 5. 获取当前鼠标位置并稍微移动一下，确保鼠标响应
                if (GetCursorPos(out POINT currentPos))
                {
                    // 稍微移动鼠标以"唤醒"它
                    SetCursorPos(currentPos.X + 1, currentPos.Y);
                    SetCursorPos(currentPos.X, currentPos.Y);
                    System.Diagnostics.Debug.WriteLine($"[MouseControlService] 鼠标位置重置: X={currentPos.X}, Y={currentPos.Y}");
                }

                _isMouseReleased = true;
                System.Diagnostics.Debug.WriteLine("[MouseControlService] ✓ 鼠标控制释放完成");
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine($"[MouseControlService] ✗ 释放鼠标控制失败: {ex.Message}");
                System.Diagnostics.Debug.WriteLine($"[MouseControlService] 错误详情: {ex.StackTrace}");
            }
        }

        /// <summary>
        /// 恢复游戏的鼠标控制 - 在覆盖层窗口隐藏时调用
        /// </summary>
        public void RestoreMouse()
        {
            try
            {
                if (!_isMouseReleased)
                {
                    System.Diagnostics.Debug.WriteLine("[MouseControlService] ⚠ 鼠标未释放，无需恢复");
                    return;
                }

                System.Diagnostics.Debug.WriteLine("[MouseControlService] 🔒 开始恢复游戏鼠标控制...");

                // 1. 恢复光标显示计数（将光标隐藏次数恢复）
                for (int i = 0; i < _cursorShowCount && i < 10; i++)
                {
                    ShowCursor(false);
                }
                System.Diagnostics.Debug.WriteLine($"[MouseControlService] 光标隐藏计数已恢复: {_cursorShowCount}次");

                // 2. 恢复鼠标裁剪区域（如果游戏之前设置了裁剪）
                if (!_savedClipRect.IsEmpty)
                {
                    bool clipRestored = ClipCursor(ref _savedClipRect);
                    System.Diagnostics.Debug.WriteLine($"[MouseControlService] 恢复鼠标裁剪区域: {(clipRestored ? "成功" : "失败")}");
                }

                // 注意：不需要手动调用SetCapture，游戏会在重新获得焦点时自行捕获鼠标

                _isMouseReleased = false;
                _cursorShowCount = 0;
                _savedClipRect = new RECT();
                System.Diagnostics.Debug.WriteLine("[MouseControlService] ✓ 鼠标控制恢复完成");
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine($"[MouseControlService] ✗ 恢复鼠标控制失败: {ex.Message}");
                System.Diagnostics.Debug.WriteLine($"[MouseControlService] 错误详情: {ex.StackTrace}");
            }
        }

        /// <summary>
        /// 强制显示鼠标光标 - 紧急情况使用
        /// </summary>
        public void ForceShowCursor()
        {
            try
            {
                System.Diagnostics.Debug.WriteLine("[MouseControlService] 🚨 强制显示鼠标光标");
                
                // 解除所有限制
                ReleaseCapture();
                ClipCursor(IntPtr.Zero);
                
                // 强制显示光标
                for (int i = 0; i < 20; i++) // 最多调用20次确保可见
                {
                    int count = ShowCursor(true);
                    if (count >= 0) break;
                }
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine($"[MouseControlService] 强制显示光标失败: {ex.Message}");
            }
        }

        /// <summary>
        /// 检查鼠标是否被释放
        /// </summary>
        public bool IsMouseReleased => _isMouseReleased;
    }
}
